<template>
  <div class="websocket-chat">
    <h2>WebSocket实时数据演示</h2>
    
    <div class="connection-status">
      <span>连接状态: </span>
      <span :class="{
        'status-connected': connectionStatus === '已连接',
        'status-disconnected': connectionStatus === '已断开',
        'status-error': connectionStatus === '连接错误'
      }">{{ connectionStatus }}</span>
      <button @click="reconnect" class="reconnect-button">重新连接</button>
    </div>
    
    <!-- 实时数据显示区域 -->
    <div v-if="latestData" class="data-panel">
      <h3>实时数据 <span class="timestamp">{{ formatTime(latestData.timestamp) }}</span></h3>
      <div class="data-grid">
        <div class="data-item">
          <div class="data-label">温度</div>
          <div class="data-value">{{ latestData.temperature }}°C</div>
        </div>
        <div class="data-item">
          <div class="data-label">湿度</div>
          <div class="data-value">{{ latestData.humidity }}%</div>
        </div>
        <div class="data-item">
          <div class="data-label">气压</div>
          <div class="data-value">{{ latestData.pressure }} hPa</div>
        </div>
        <div class="data-item">
          <div class="data-label">状态</div>
          <div class="data-value" :class="{'status-warning': latestData.status === 'warning'}">{{ latestData.status === 'warning' ? '警告' : '正常' }}</div>
        </div>
      </div>
      
      <h4>设备数据</h4>
      <div class="devices-list">
        <div v-for="device in latestData.devices" :key="device.id" class="device-item">
          <span class="device-name">{{ device.name }}</span>
          <div class="device-value-container">
            <div class="device-value-bar" :style="{width: device.value + '%'}"></div>
            <span class="device-value-text">{{ device.value }}%</span>
          </div>
        </div>
      </div>
    </div>
    
    <div class="messages-container">
      <div v-for="(message, index) in messages" :key="index" 
           :class="['message', `message-${message.type}`]">
        <span class="message-content">{{ message.content }}</span>
      </div>
    </div>
    
    <div class="message-input">
      <input 
        v-model="inputMessage" 
        @keyup.enter="sendMessage" 
        placeholder="输入消息..."
        :disabled="connectionStatus !== '已连接'"
      />
      <button 
        @click="sendMessage" 
        :disabled="connectionStatus !== '已连接'"
        class="send-button"
      >发送</button>
    </div>
  </div>
</template>

<script>
export default {
  name: 'WebSocketChat',
  data() {
    return {
      // WebSocket连接状态
      connectionStatus: '未连接',
      // 消息列表
      messages: [],
      // 输入消息
      inputMessage: '',
      // WebSocket实例
      ws: null,
      // 最新接收的数据
      latestData: null
    };
  },
  methods: {
    // 连接WebSocket服务器
    connectWebSocket() {
      console.log('【WebSocket初始化】', '正在连接到WebSocket服务器ws://localhost:8080');
      // 创建WebSocket连接
      this.ws = new WebSocket('ws://localhost:8080');
      
      // 连接建立时的回调
      this.ws.onopen = () => {
        console.log('【WebSocket连接】', '已成功连接到WebSocket服务器');
        this.connectionStatus = '已连接';
        this.messages.push({ type: 'system', content: '已连接到WebSocket服务器' });
      };
      
      // 接收消息的回调
      this.ws.onmessage = (event) => {
        // 在控制台打印接收到的原始数据
        console.log('【WebSocket接收】', event.data);
        
        try {
          // 尝试解析JSON数据
          const data = JSON.parse(event.data);
          
          // 在控制台打印解析后的JSON数据
          console.log('【WebSocket接收-解析JSON】', data);
          
          // 检查是否为服务器推送的数据格式
          if (data.timestamp && data.temperature && data.humidity) {
            // 更新最新数据
            this.latestData = data;
            // 添加系统消息
            this.messages.push({ 
              type: 'system', 
              content: `收到服务器数据更新 (${this.formatTime(data.timestamp)})` 
            });
            
            // 如果状态为警告，添加警告消息
            if (data.status === 'warning') {
              this.messages.push({ 
                type: 'error', 
                content: `警告: 系统状态异常！温度: ${data.temperature}°C, 湿度: ${data.humidity}%` 
              });
            }
          } else {
            // 普通JSON消息
            this.messages.push({ 
              type: 'received', 
              content: `JSON数据: ${JSON.stringify(data)}` 
            });
          }
        } catch (e) {
          // 不是JSON格式，作为普通文本消息处理
          console.log('【WebSocket接收-非JSON格式】', event.data, e);
          this.messages.push({ type: 'received', content: event.data });
        }
      };
      
      // 连接关闭时的回调
      this.ws.onclose = () => {
        console.log('【WebSocket关闭】', '与WebSocket服务器的连接已断开');
        this.connectionStatus = '已断开';
        this.messages.push({ type: 'system', content: '与WebSocket服务器的连接已断开' });
      };
      
      // 连接错误时的回调
      this.ws.onerror = () => {
        console.log('【WebSocket错误】', '连接发生错误');
        this.connectionStatus = '连接错误';
        this.messages.push({ type: 'error', content: '连接错误' });
      };
    },
    
    // 发送消息
    sendMessage() {
      if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
        console.log('【WebSocket发送失败】', '未连接到WebSocket服务器');
        this.messages.push({ type: 'error', content: '未连接到WebSocket服务器' });
        return;
      }
      
      if (this.inputMessage.trim() === '') {
        return;
      }
      
      // 在控制台打印发送的消息
      console.log('【WebSocket发送】', this.inputMessage);
      
      // 发送消息
      this.ws.send(this.inputMessage);
      
      // 添加到消息列表
      this.messages.push({ type: 'sent', content: this.inputMessage });
      
      // 清空输入框
      this.inputMessage = '';
    },
    
    // 重新连接
    reconnect() {
      console.log('【WebSocket重连】', '正在尝试重新连接WebSocket服务器');
      if (this.ws) {
        this.ws.close();
      }
      this.connectWebSocket();
    },
    
    // 格式化时间戳
    formatTime(timestamp) {
      const date = new Date(timestamp);
      return date.toLocaleTimeString('zh-CN', { 
        hour: '2-digit', 
        minute: '2-digit', 
        second: '2-digit',
        hour12: false
      });
    }
  },
  // 组件挂载时连接WebSocket
  mounted() {
    console.log('【组件生命周期】', 'WebSocketChat组件已挂载，开始连接WebSocket');
    this.connectWebSocket();
  },
  // 组件卸载时关闭WebSocket连接
  beforeUnmount() {
    console.log('【组件生命周期】', 'WebSocketChat组件即将卸载，关闭WebSocket连接');
    if (this.ws) {
      this.ws.close();
    }
  }
};
</script>

<style scoped>
.websocket-chat {
  max-width: 700px;
  margin: 0 auto;
  padding: 20px;
  border: 1px solid #ddd;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

h2 {
  text-align: center;
  margin-bottom: 20px;
  color: #333;
}

h3 {
  margin: 15px 0 10px;
  color: #444;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

h4 {
  margin: 15px 0 10px;
  color: #555;
}

.timestamp {
  font-size: 0.8em;
  color: #777;
  font-weight: normal;
}

.connection-status {
  display: flex;
  align-items: center;
  margin-bottom: 15px;
  padding: 8px;
  background-color: #f5f5f5;
  border-radius: 4px;
}

/* 数据面板样式 */
.data-panel {
  background-color: #f9f9f9;
  border: 1px solid #ddd;
  border-radius: 8px;
  padding: 15px;
  margin-bottom: 20px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
}

.data-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 15px;
  margin-top: 10px;
}

.data-item {
  background-color: white;
  border-radius: 6px;
  padding: 12px;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
}

.data-label {
  font-size: 0.9em;
  color: #666;
  margin-bottom: 5px;
}

.data-value {
  font-size: 1.4em;
  font-weight: bold;
  color: #333;
}

.status-warning {
  color: #f44336;
}

/* 设备列表样式 */
.devices-list {
  margin-top: 10px;
}

.device-item {
  display: flex;
  align-items: center;
  margin-bottom: 10px;
  background-color: white;
  padding: 10px;
  border-radius: 6px;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
}

.device-name {
  width: 80px;
  font-weight: 500;
}

.device-value-container {
  flex: 1;
  height: 20px;
  background-color: #f0f0f0;
  border-radius: 10px;
  overflow: hidden;
  position: relative;
}

.device-value-bar {
  height: 100%;
  background-color: #4CAF50;
  border-radius: 10px;
  transition: width 0.3s ease;
}

.device-value-text {
  position: absolute;
  right: 10px;
  top: 50%;
  transform: translateY(-50%);
  font-size: 0.8em;
  font-weight: bold;
  color: #333;
}

.status-connected {
  color: green;
  font-weight: bold;
}

.status-disconnected {
  color: #888;
}

.status-error {
  color: red;
}

.reconnect-button {
  margin-left: auto;
  padding: 5px 10px;
  background-color: #4CAF50;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

.reconnect-button:hover {
  background-color: #45a049;
}

.messages-container {
  height: 300px;
  overflow-y: auto;
  border: 1px solid #ddd;
  border-radius: 4px;
  padding: 10px;
  margin-bottom: 15px;
  background-color: #f9f9f9;
}

.message {
  margin-bottom: 10px;
  padding: 8px 12px;
  border-radius: 4px;
  max-width: 80%;
  word-break: break-word;
}

.message-sent {
  background-color: #dcf8c6;
  margin-left: auto;
  border-radius: 8px 0 8px 8px;
}

.message-received {
  background-color: #fff;
  border: 1px solid #ddd;
  border-radius: 0 8px 8px 8px;
}

.message-system {
  background-color: #f0f0f0;
  color: #666;
  text-align: center;
  margin: 5px auto;
  font-style: italic;
  max-width: 100%;
}

.message-error {
  background-color: #ffebee;
  color: #d32f2f;
  text-align: center;
  margin: 5px auto;
  max-width: 100%;
}

.message-input {
  display: flex;
  gap: 10px;
}

input {
  flex: 1;
  padding: 10px;
  border: 1px solid #ddd;
  border-radius: 4px;
  font-size: 14px;
}

input:disabled {
  background-color: #f5f5f5;
  cursor: not-allowed;
}

.send-button {
  padding: 10px 15px;
  background-color: #1976d2;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-weight: bold;
}

.send-button:hover:not(:disabled) {
  background-color: #1565c0;
}

.send-button:disabled {
  background-color: #cccccc;
  cursor: not-allowed;
}
</style>